package com.example.socket.longlink;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

/**
 * @author hej
 * @date 2024/9/11 18:42
 */
public class LongConnectionServer {
    private String message = "message", header = "header", messageClass = "messageClass",
            transactionID = "transactionID", messageVersion = "messageVersion", reply = "reply",
            location = "location", routeID = "routeID", routeName = "routeName", equipmentID = "equipmentID",
            equipmentName = "equipmentName", zoneID = "zoneID", zonePos = "zonePos",
            zoneName = "zoneName", laneNo = "laneNo", controllerGuid = "controllerGuid",
            body = "body", interlocks = "interlocks", interlock = "interlock", lockRefId = "lockRefId",
            mesErrorCode = "mesErrorCode", mesErrorText = "mesErrorText";
    public static void main(String[] args){
        int port = 12345;

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("服务器已启动，等待客户端连接...");

            //while (true) {
                Socket clientSocket = serverSocket.accept();
                System.out.println("客户端已连接：" + clientSocket.getInetAddress());
                // 启动新线程处理客户端连接
                new Thread (new ClientHandler(clientSocket)).start();
            //}
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ClientHandler implements Runnable {
    private Socket clientSocket;

    public ClientHandler(Socket socket) {
        this.clientSocket = socket;
    }

    @Override
    public void run() {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)){
            int i=0;
            while(true){
                try {
                    Thread.sleep(1000);
                    LockFeed lockFeed = QueueHolder.get().take();
                    //向客户端写xml文件
                    DataOutputStream outStream = new DataOutputStream(clientSocket.getOutputStream());
                    // 定义工厂 API，使应用程序能够从 XML 文档获取生成 DOM 对象树的解析器
                    DocumentBuilderFactory factory = DocumentBuilderFactory
                            .newInstance();
                    // 定义 API， 使其从 XML 文档获取 DOM 文档实例。使用此类，应用程序员可以从 XML 获取一个 Document
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    // Document 接口表示整个 HTML 或 XML 文档。从概念上讲，它是文档树的根，并提供对文档数据的基本访问
                    Document document = builder.newDocument();
                    //组织生产xml文件内容
                    Element message = document.createElement("message");
                    document.appendChild(message);

                    Element header = document.createElement("header");
                    header.setAttribute("messageClass", "409");
                    header.setAttribute("transactionID", "57392");
                    header.setAttribute("messageVersion", "2.0");
                    header.setAttribute("reply", "1");

                    Element location = document.createElement("location");
                    location.setAttribute("routeID", "1");
                    location.setAttribute("routeName", "S61A");
                    location.setAttribute("equipmentID", "2");
                    location.setAttribute("equipmentName", "NPM-W2-0002");
                    location.setAttribute("zoneID", "2");
                    location.setAttribute("zonePos", "2");
                    location.setAttribute("zoneName", "Zone-2");
                    location.setAttribute("laneNo", "0");
                    location.setAttribute("controllerGuid", "panacim-208756f4ce2f");
                    header.appendChild(location);
                    message.appendChild(header);


                    Element body = document.createElement("body");
                    Element interlocks = document.createElement("interlocks");
                    //document.appendChild(interlocks);
                    Element interlock = document.createElement("interlock");
                    interlock.setAttribute("lockRefId", "1234");
                    interlock.setAttribute("mesErrorCode", lockFeed.getMesErrorCode());
                    interlock.setAttribute("mesErrorText", "-----MES-MSD-lock---");
                    interlocks.appendChild(interlock);

                    body.appendChild(interlocks);
                    message.appendChild(body);


                    TransformerFactory tf = TransformerFactory.newInstance();
                    // 此抽象类的实例能够将源树转换为结果树
                    Transformer transformer;
                    transformer = tf.newTransformer();

                    DOMSource source = new DOMSource(document);
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    transformer.transform(source, new StreamResult(bos));

                    //保存xml文件
                    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                    StreamResult result = new StreamResult(new java.io.File("gogogo.xml"));
                    // 输出到文件
                    transformer.transform(source, result);


                    String xmlStr = bos.toString();
                    //outStream.writeUTF(xmlStr);

                    String lenthEncode = "UTF-8";
                    long len =  xmlStr.getBytes(lenthEncode).length;
                    String length=String.format("%06d",len);
                    xmlStr = length+ xmlStr;
                    byte[] bt = xmlStr.getBytes(lenthEncode);
                    outStream.write(bt);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } catch (ParserConfigurationException e) {
                    throw new RuntimeException(e);
                } catch (TransformerConfigurationException e) {
                    throw new RuntimeException(e);
                } catch (TransformerException e) {
                    throw new RuntimeException(e);
                }
                // 回应消息
                out.println("服务器回应: " + i++);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
